/*
	Copyright (c) 2008, Grant Jones <grant@podtronics.com>.
	All rights reserved.

	Redistribution and use in source and binary forms, with or
	without modification, are permitted provided that the following
	conditions are met:

		Redistributions of source code must retain the above copyright
		notice, this list of conditions and the following disclaimer.
		
		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in
		the documentation and/or other materials provided with the
		distribution.
		
		Neither the name of the gxjones.com nor the names of its
		contributors may be used to endorse or promote products derived
		from this software without specific prior written permission.
	
	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
	FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
	COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
	OF THE POSSIBILITY OF SUCH DAMAGE.
	
	http://www.opensource.org/licenses/bsd-license.php
*/

/*
 *  edb_main.c
 *  scatterd
 *
 *  Created by Grant Jones on 3/1/08.
 *
 */

#include "edb_main.h"
#include "edb_msg_parser.h"
#include "edb_msg_utils.h"

static void usage(void)
{
    printf(PACKAGE " " VERSION "\n");
    printf(	"-h            this help information\n"
			"-p <num>      TCP port number to listen on for shell connections (default: 11911)\n"
			"-H <num>      TCP port number to listen on for HTTP connections (default: 8080)\n"
			"-d            run as a daemon\n"
			"-M            run database from memory (-n flag is ignored)\n"
			"-n <file>     default database filename\n"
			"-P <file>     write pid to <file>\n"
			"-r <file>     the main HTTP server lua file\n"
			"-S            disables writes to edbsync\n"
			"-c <out_file> compacts the database file into out_file then exits\n"
			"-k <file>     dumps the tag file specified by file to stdout\n"
			"-D <opts>     Enable a debug output mode (opts may be: STDOUT,MEMPOOL,MEMPOOL2,CONNECT)\n" );
}

static void sig_handler(const int sig) {
    printf("SIGINT handled.\n");
    exit(EXIT_SUCCESS);
}


int edb_main_stop( ProgramContextStruct *pcs )
{
	return 0;
}

void edb_write_pid( const char *filename )
{
	pid_t pid = getpid();
	
	FILE *fp = fopen( filename, "w" );
	if(!fp)
	{
		fprintf(stderr, "Unable to write PID to file: %s\n", strerror(errno) );
		return;
	}
	
	fprintf(fp, "%ld\n", (long int)pid );
	fclose(fp);
	
}
int edb_dump( const char *filename )
{
	TagManagerStruct *src = tagm_open(filename);
	tagm_dumpTag( src, stdout, 0ULL, 0 );
	tagm_close(src);
	return 0;
}
int edb_compact( const char *src_file, const char *dest_file )
{
	TagManagerStruct *src = tagm_open(src_file);
	TagManagerStruct *dst = tagm_open(dest_file);
	int result = 0;
	
	if( tagm_duplicateTagFile( src, dst, 0ULL, 0ULL ) )
	{
		fprintf(stderr, "File compaction failed\n");
		result = -1;
	}
	
	tagm_close(src);
	tagm_close(dst);

	return result;
}

int edb_main( ProgramContextStruct *pcs, int argc, char *argv[] )
{
	/* You forget so easy, we ride tonight, ghost horses */
	
	char c;
	
	memset( pcs, 0, sizeof(ProgramContextStruct) );
	
	
	
	edb_log_setout( NULL );

#ifndef WIN32	
	mempool_init(&pcs->stralloc, getpagesize() );
#else
	mempool_init(&pcs->stralloc, 8192 );
#endif
	pcs->net_shell_port = DEFAULT_SHELL_PORT;

#ifndef NO_REST_HTTP_SERVER	
	pcs->net_http_port = DEFAULT_HTTP_PORT;
	
	/* the HTTP server will run pretty gimped (as in it won't do anything) without this set: */
	pcs->net_http_file = NULL;
#endif
	
	char *db_name = "default.db";
	char *compact_filename = NULL;
	char *dump_filename = NULL;
	
	pcs->domains = cmap_new(NULL);
	pcs->rt_db_ptr = mempool_malloc_named(pcs->domains->mempool, sizeof(rtree_t), "default database tree");

	/* handle SIGINT */
	signal(SIGINT, sig_handler);
	
	// Handle arguments:
    while ((c = getopt(argc, argv, "hP:D:SH:r:n:c:k:M")) != -1)
	{
		switch (c)
		{
        case 'h':
            usage();
            exit(EXIT_SUCCESS);	
			break;
		case 'P':
			edb_write_pid( optarg );
			break;
		case 'D':
			if(strncmp(optarg, "MEMPOOL", 7 ) == 0)
				pcs->bDumpMemOnDC = 1;
			else if(strncmp(optarg, "CONNECT", 7 ) == 0)
				pcs->bDebugConnect = 1;
			else if(strncmp(optarg, "MEMPOOL2", 8 ) == 0)
				pcs->bDumpMemOnReq = 1;
			else if(strncmp(optarg, "STDOUT", 6 ) == 0)
				edb_log_setout( stdout );				
				
			break;
		case 'S':
			pcs->bGlobalSyncDisabled = 1;
			break;
        case 'd':
#ifndef __AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5		
			daemon(1, 0); // nochdir, noclose
#endif			
			break;
		case 'p':
			pcs->net_shell_port = atoi(optarg);
			break;
		case 'M':
			db_name = NULL;
			break;
		case 'n':
			db_name = edb_strdup( &pcs->stralloc, optarg, strlen(optarg), "default database filename" );
			break;
		case 'k':
			dump_filename = edb_strdup( &pcs->stralloc, optarg, strlen(optarg), "dump database filename" );
			break;
		case 'c':
			compact_filename = edb_strdup( &pcs->stralloc, optarg, strlen(optarg), "compaction output filename" );
			break;			
#ifndef NO_REST_HTTP_SERVER	
		case 'H':
			pcs->net_http_port = atoi(optarg);
			break;
		case 'r':
			pcs->net_http_file = edb_strdup( &pcs->stralloc, optarg, strlen(optarg), "net HTTP handler file" );
			break;
#endif
		}
		
	}
	if( dump_filename )
		exit(edb_dump(dump_filename));

	if( compact_filename )
		exit(edb_compact( db_name, compact_filename ));

	if( rtree_open( pcs->rt_db_ptr, db_name, 0 ) )
	{
		fprintf(stderr, "Failed to open database: %s\n", db_name );
		exit(-1);
	}


	return 0;
}








